import 'package:flutter/cupertino.dart';
import 'package:rapid_kit/rapid_kit.dart';
import '../../../sample/configure/constants.dart';

/// 探鸽公共页面 - 播放相关
abstract class ComposedPlayer {
  final String _tag = '_composed_player';

  late Player playerOfCamera0;
  Player? playerOfCamera1;
  Player? playerOfCamera2;

  bool audioMuted = false;
  bool videoCapturing = false;
  bool videoRecording = false;

  RenderStateListener? renderStateListener;

  ComposedPlayer();

  @mustCallSuper
  void prepare(int cameraCount) {
    playerOfCamera0 = Player.create();
    playerOfCamera0.buffering(SampleConstants.videoBufferingEnabled);
    playerOfCamera0.onRenderState = (state) {
      renderStateListener?.call(state);
    };

    playerOfCamera0.onPixelSizeChanged = (width, height) {
      // use width and height to adjust the size of the player or other scean.
    };

    playerOfCamera0.onPresentationTimestamp = (pts) {
      // use pts to update your UI (like timeline) or other scean.
    };

    playerOfCamera0.onUniversalTimestamp = (uts) {
      // use uts to update your UI (like timeline) or other scean.
    };

    if (cameraCount >= 2) {
      playerOfCamera1 = Player.create();
      playerOfCamera1?.buffering(SampleConstants.videoBufferingEnabled);
      playerOfCamera1?.bindingPrimaryPlayer(playerOfCamera0);
    }

    if (cameraCount >= 3) {
      playerOfCamera2 = Player.create();
      playerOfCamera2?.bindingPrimaryPlayer(playerOfCamera0);
    } // if you have more than 3 cameras, you can add more player here
  }

  bool existCamera2() => playerOfCamera2 != null;
  bool existCamera1() => playerOfCamera1 != null;

  Widget textureOfCamera0() => playerOfCamera0.texture();
  Widget textureOfCamera1() => playerOfCamera1?.texture() ?? Container();
  Widget textureOfCamera2() => playerOfCamera2?.texture() ?? Container();

  void mute() {
    if (playerOfCamera0.isMute()) {
      playerOfCamera0.mute(false);
    } else {
      playerOfCamera0.mute(true);
    }
    audioMuted = playerOfCamera0.isMute();
  }

  Future<int> capture() async {
    final granted = await RuntimePermissions.accessGranted(PermissionType.gallery);
    if (!granted) {
      final ret = await RuntimePermissions.requestAccess(PermissionType.gallery);
      if (ret == PermissionState.denied) return -3;
      return -2;
    }

    if (videoRecording) {
      videoRecording = false;
      return await playerOfCamera0.capture() ? 1 : -1;
    } else {
      videoRecording = true;
      return await playerOfCamera0.capture() ? 0 : -1;
    }
  }

  Future<int> record() async {
    final granted = await RuntimePermissions.accessGranted(PermissionType.gallery);
    if (!granted) {
      final ret = await RuntimePermissions.requestAccess(PermissionType.gallery);
      if (ret == PermissionState.denied) return -3;
      return -2;
    }

    if (videoCapturing) {
      final ret = await playerOfCamera0.stopRecord();
      videoCapturing = false;
      return ret ? 1 : -1;
    } else {
      final ret = await playerOfCamera0.startRecord();
      videoCapturing = true;
      return ret ? 0 : -1;
    }
  }

  @mustCallSuper
  void resume() {
    playerOfCamera0.start();
    playerOfCamera1?.start();
    playerOfCamera2?.start();
  }

  @mustCallSuper
  void pause() {
    playerOfCamera0.stop();
    playerOfCamera1?.stop();
    playerOfCamera2?.stop();
  }

  @mustCallSuper
  void dispose() {
    playerOfCamera0.destroy();
    playerOfCamera1?.destroy();
    playerOfCamera2?.destroy();
  }
}
